home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i094: Shared memory emulation for 4.2BSD, Part01/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: libes@cme-durer.ARPA (Don Libes)
- Posting-number: Volume 14, Issue 94
- Archive-name: sharedmem/part01
-
- This system emulates a shared memory system for 4.2BSD. A common
- memory server handles requests to access shared variables. Because
- communication uses TCP/IP, processes may be distributed across
- machines.
-
- The system is all user level code and requires no kernel
- modifications. This implementation provides interfaces for C and
- Franz Lisp. It is known to work on Sun UNIX releases from 1.0 to 3.4.
-
- The system is documented by the files in the doc directory.
- doc/usenix contains a paper that was presented at the Summer 1985
- Usenix Conference. The system has changed somewhat since then.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 4)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1424 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThe NBS Common Memory System (CMS)
- XSept 25, 1987
- X
- XThis system emulates a shared memory system for 4.2BSD. A common
- Xmemory server handles requests to access shared variables. Because
- Xcommunication uses TCP/IP, processes may be distributed across
- Xmachines.
- X
- XThe system is all user level code and requires no kernel
- Xmodifications. This implementation provides interfaces for C and
- XFranz Lisp. It is known to work on Sun UNIX releases from 1.0 to
- X3.4.
- X
- XThe system is documented by the files in the doc directory.
- Xdoc/usenix contains a paper that was presented at the Summer 1985
- XUsenix Conference. The system has changed somewhat since then.
- X
- XInstallation instructions
- X
- XThis package depends upon a tiny communications library called
- Xstreamlib which must be installed first.
- X
- X cd stream
- X cat README
- X
- Xand follow the directions in there.
- X
- XOnce you have installed streamlib, change to the common memory
- Xsource directory and run make.
- X
- X cd ../src
- X make install
- X
- XIf you would like to try out some of the examples, type:
- X
- X make examples
- X
- XThe examples are numbered as sets. I.e. client1 runs with server1.
- XThe most interesting is server1y, server1z, client1a and client1b.
- XRun these in 4 different windows. They are documented by their
- Xsource and serve as coding examples.
- X
- XDon Libes
- XNational Bureau of Standards
- XMetrology Building, Room A-127
- XGaithersburg, MD 20899
- X(301) 975-3535
- X
- Xlibes@cme-durer.arpa
- Xuunet!cme-durer!libes
- X
- X
- END_OF_FILE
- if test 1424 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'cms.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cms.3'\"
- else
- echo shar: Extracting \"'cms.3'\" \(449 characters\)
- sed "s/^X//" >'cms.3' <<'END_OF_FILE'
- X.TH CMS 3NBS "11 January 1988"
- X.SH NAME
- Xshared memory system emulator
- X.SH DESCRIPTION
- X.PP
- XThis system emulates a shared memory system. A common memory
- Xserver handles requests to access shared variables. Because
- Xcommunication uses TCP/IP, processes may be distributed across
- Xmachines.
- X.PP
- XFor further information read the documents in the doc directory
- Xthat comes with the common memory source. There are several
- Xexamples in the source directory.
- END_OF_FILE
- if test 449 -ne `wc -c <'cms.3'`; then
- echo shar: \"'cms.3'\" unpacked with wrong size!
- fi
- # end of 'cms.3'
- fi
- if test ! -d 'doc' ; then
- echo shar: Creating directory \"'doc'\"
- mkdir 'doc'
- fi
- if test ! -d 'doc/usenix' ; then
- echo shar: Creating directory \"'doc/usenix'\"
- mkdir 'doc/usenix'
- fi
- if test ! -d 'src' ; then
- echo shar: Creating directory \"'src'\"
- mkdir 'src'
- fi
- if test -f 'src/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/README'\"
- else
- echo shar: Extracting \"'src/README'\" \(247 characters\)
- sed "s/^X//" >'src/README' <<'END_OF_FILE'
- XAm in the process of implementing a way to get the names of the open cm
- Xvariables from the cmm. Idea is to reserve a variable, say, cm_variable_names
- Xwhich is written by the cmm whenever a new variable is declared (or the last
- Xlink is deleted).
- X
- END_OF_FILE
- if test 247 -ne `wc -c <'src/README'`; then
- echo shar: \"'src/README'\" unpacked with wrong size!
- fi
- # end of 'src/README'
- fi
- if test -f 'src/client1a.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/client1a.c'\"
- else
- echo shar: Extracting \"'src/client1a.c'\" \(795 characters\)
- sed "s/^X//" >'src/client1a.c' <<'END_OF_FILE'
- X/* client1a.c
- XThis process, a, writes a string to variable a_var.
- XIt then checks variable b_var for a new value, and if it is, prints it.
- XIt then sleeps for 3 seconds.
- X*/
- X#include "cm.h"
- X
- X#define BUFFER_LENGTH 1000
- Xchar a_data[BUFFER_LENGTH];
- X
- Xcm_value a_val = {a_data,BUFFER_LENGTH,0,0}, b_val = {0,0,0,1};
- X
- Xmain()
- X{
- X cm_variable *a_var, *b_var;
- X int seqno = 0;
- X
- X if (0> cm_init("a",0,0)) exit(-1);
- X
- X if (!(a_var = cm_declare("a_var",CM_ROLE_NONXWRITER)))
- X exit(-1);
- X if (!(b_var = cm_declare("b_var",CM_ROLE_READER|CM_ROLE_WAKEUP)))
- X exit(-1);
- X
- X for (;;) {
- X sprintf(a_data,"Message from a. seq #%d",seqno++);
- X a_val.size = strlen(a_data) + 1;
- X cm_set_value(a_var,&a_val);
- X cm_sync(CM_NO_WAIT);
- X if (cm_get_new_value(b_var,&b_val))
- X printf("b_var: %s\n",b_val.data);
- X sleep(3);
- X }
- X}
- END_OF_FILE
- if test 795 -ne `wc -c <'src/client1a.c'`; then
- echo shar: \"'src/client1a.c'\" unpacked with wrong size!
- fi
- # end of 'src/client1a.c'
- fi
- if test -f 'src/client1b.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/client1b.c'\"
- else
- echo shar: Extracting \"'src/client1b.c'\" \(807 characters\)
- sed "s/^X//" >'src/client1b.c' <<'END_OF_FILE'
- X/*
- XThis process, b, writes a string to variable b_var.
- XIt then checks variable a_var for a new value, and if it is, prints it.
- XIt then sleeps for 5 seconds.
- X*/
- X#include <sys/time.h>
- X#include "cm.h"
- X
- X#define BUFFER_LENGTH 1000
- Xchar b_data[BUFFER_LENGTH];
- X
- Xcm_value a_val = {0,0,0,1}, b_val = {b_data,BUFFER_LENGTH,0,0};
- X
- Xmain()
- X{
- X cm_variable *a_var, *b_var;
- X int seqno = 0;
- X
- X if (0> cm_init("b",0,0)) exit(-1);
- X
- X if (!(a_var = cm_declare("a_var",CM_ROLE_READER|CM_ROLE_WAKEUP)))
- X exit(-1);
- X if (!(b_var = cm_declare("b_var",CM_ROLE_NONXWRITER)))
- X exit(-1);
- X
- X for (;;) {
- X sprintf(b_data,"Message from b. seq #%d",seqno++);
- X b_val.size = strlen(b_data) + 1;
- X cm_set_value(b_var,&b_val);
- X cm_sync(CM_NO_WAIT);
- X if (cm_get_new_value(a_var,&a_val))
- X printf("a_var: %s\n",a_val.data);
- X sleep(5);
- X }
- X}
- X
- END_OF_FILE
- if test 807 -ne `wc -c <'src/client1b.c'`; then
- echo shar: \"'src/client1b.c'\" unpacked with wrong size!
- fi
- # end of 'src/client1b.c'
- fi
- if test -f 'src/client2.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/client2.c'\"
- else
- echo shar: Extracting \"'src/client2.c'\" \(1056 characters\)
- sed "s/^X//" >'src/client2.c' <<'END_OF_FILE'
- X/* client2.c
- X this client writes the following to common memory:
- Xs_var: a line read from stdin
- Xi_var: the length of s_var
- Xd_var: a random double variable
- X*/
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xcm_variable *i_var, *d_var, *s_var;
- Xcm_value i_val, d_val, s_val;
- Xdouble d_val_data = 3.14159;
- X
- Xchar s_val_data[1000];
- Xint i_val_data;
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X if (argc>1) printf("going to host %s for cmm\n",argv[1]);
- X if (0 > cm_init("don",(argc>1?argv[1]:(char *)0),0)) exit(-1);
- X
- X s_var = cm_declare("s_var",CM_ROLE_NONXWRITER);
- X i_var = cm_declare("i_var",CM_ROLE_NONXWRITER);
- X d_var = cm_declare("d_var",CM_ROLE_NONXWRITER);
- X
- X d_val.data = (char *)&d_val_data;
- X d_val.size = sizeof(d_val_data);
- X s_val.data = s_val_data;
- X i_val.data = (char *)&i_val_data;
- X
- X while (TRUE) {
- X cm_set_value(d_var,&d_val);
- X
- X printf("enter string for s_val: ");
- X gets(s_val_data);
- X s_val.size = strlen(s_val_data);
- X cm_set_value(s_var,s_val);
- X
- X i_val_data = strlen(s_val_data);
- X cm_set_value(i_var,&i_val);
- X
- X if (0 > cm_sync(CM_NO_WAIT)) return;
- X }
- X}
- END_OF_FILE
- if test 1056 -ne `wc -c <'src/client2.c'`; then
- echo shar: \"'src/client2.c'\" unpacked with wrong size!
- fi
- # end of 'src/client2.c'
- fi
- if test -f 'src/client8.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/client8.c'\"
- else
- echo shar: Extracting \"'src/client8.c'\" \(382 characters\)
- sed "s/^X//" >'src/client8.c' <<'END_OF_FILE'
- X/* client8.c - constantly write a variable to common memory (see server8.c) */
- X
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xcm_variable *variable;
- Xcm_value value = { "foo", 4, 4, 0};
- X
- Xmain()
- X{
- X if (0>cm_init("constant writer",0,0)) exit(-1);
- X
- X if (!(variable = cm_declare("variable",CM_ROLE_XWRITER))) exit(-1);
- X
- X while (1) {
- X cm_set_value(variable,&value);
- X cm_sync(CM_NO_WAIT);
- X }
- X}
- END_OF_FILE
- if test 382 -ne `wc -c <'src/client8.c'`; then
- echo shar: \"'src/client8.c'\" unpacked with wrong size!
- fi
- # end of 'src/client8.c'
- fi
- if test -f 'src/cm.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm.h'\"
- else
- echo shar: Extracting \"'src/cm.h'\" \(269 characters\)
- sed "s/^X//" >'src/cm.h' <<'END_OF_FILE'
- X/* cm.h - include common memory include files */
- X
- X#ifndef _TIME_
- X#include <sys/time.h>
- X#endif
- X
- X#include "cm_constants.h"
- X#include "cm_var.h"
- X#include "cm_sd.h"
- X#include "cm_interface.h"
- X#include "cm_slot.h"
- X#include "cm_msg.h"
- X#include "cm_sync.h"
- X#include "cm_time.h"
- END_OF_FILE
- if test 269 -ne `wc -c <'src/cm.h'`; then
- echo shar: \"'src/cm.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm.h'
- fi
- if test -f 'src/cm.lisp' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm.lisp'\"
- else
- echo shar: Extracting \"'src/cm.lisp'\" \(1622 characters\)
- sed "s/^X//" >'src/cm.lisp' <<'END_OF_FILE'
- X ; load in calls for common memory package
- X ; Don Libes
- X
- X(cfasl '/usr/local/lib/Luser.o '_Lcm_init 'cm_init "function"
- X "/usr/local/lib/libcm.a /usr/local/lib/libstream.a")
- X(getaddress
- X '_Lcm_declare 'cm_declare "integer-function"
- X '_Lcm_undeclare 'cm_undeclare "subroutine"
- X '_Lcm_sync 'cm_sync "integer-function"
- X '_Lcm_set_value 'cm_set_value "subroutine"
- X '_Lcm_get_value 'cm_get_value "subroutine"
- X '_Lcm_set_new_command_value 'cm_set_new_command_value "integer-function"
- X '_Lcm_new_command_pending 'cm_new_command_pending "integer-function"
- X '_Lcm_get_new_command_value 'cm_get_new_command_value "integer-function"
- X '_Lcm_status_equal 'cm_status_equal "integer-function"
- X '_Lcm_status_synchronized 'cm_status_synchronized "integer-function"
- X '_Lcm_set_status_value 'cm_set_status_value "subroutine"
- X '_Lcm_print_variable 'cm_print_variable "subroutine"
- X '_Lcm_exit 'cm_exit "subroutine"
- X)
- X
- X; access types, i.e. roles
- X(setq oldibase ibase)
- X(setq ibase 8)
- X(setq CM_ROLE_NULL 000)
- X(setq CM_ROLE_READER 001)
- X(setq CM_ROLE_WAKEUP 002)
- X(setq CM_ROLE_NONXWRITER 004)
- X(setq CM_ROLE_NONEXCLUSIVE_WRITER 004)
- X(setq CM_ROLE_EXCLUSIVE_WRITER 014)
- X(setq CM_ROLE_XWRITER 014)
- X(setq ibase oldibase)
- X
- X(setq CM_WAIT 0)
- X(setq CM_NO_WAIT 1)
- X(setq CM_WAIT_FOR_ALL 0)
- X(setq CM_WAIT_AT_MOST_ONCE 2)
- X(setq CM_WAIT_READ 4)
- X
- X;(setq CM_WAIT 0)
- X;(setq CM_NO_WAIT 1)
- X;(setq CM_WAIT_FOR_ALL 2)
- X;(setq CM_WAIT_AT_MOST_ONCE 3)
- X
- X; define common memory value
- X(c-declare
- X (struct cm_value
- X (data * char)
- X (msize unsigned-short)
- X (size unsigned-short)
- X (mallocable char)
- X )
- X)
- END_OF_FILE
- if test 1622 -ne `wc -c <'src/cm.lisp'`; then
- echo shar: \"'src/cm.lisp'\" unpacked with wrong size!
- fi
- # end of 'src/cm.lisp'
- fi
- if test -f 'src/cm_bytestuff.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_bytestuff.h'\"
- else
- echo shar: Extracting \"'src/cm_bytestuff.h'\" \(372 characters\)
- sed "s/^X//" >'src/cm_bytestuff.h' <<'END_OF_FILE'
- X/* cm_bytestuff.h - byte stuffing aids */
- X
- X/* #byteadd is used to add offsets to structures */
- X/*#define byteadd(a,b) (((int)a) + ((int)b) + (((int)a) + (int)b) % 2)*/
- X#define byteadd(a,b) (align(((int)(a)) + ((int)(b))))
- X
- X/* align converts rounds up addresses if they are odd */
- X/* if this is not done, longword stores fail on the 68000 */
- X#define align(x) ((x) + (x)%2)
- END_OF_FILE
- if test 372 -ne `wc -c <'src/cm_bytestuff.h'`; then
- echo shar: \"'src/cm_bytestuff.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_bytestuff.h'
- fi
- if test -f 'src/cm_constants.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_constants.h'\"
- else
- echo shar: Extracting \"'src/cm_constants.h'\" \(445 characters\)
- sed "s/^X//" >'src/cm_constants.h' <<'END_OF_FILE'
- X#define CM_PORT 1525
- X
- X/* maximums */
- X#define CM_MSGSIZE 100000/* max length of all variables
- X sent to server at one time */
- X#define CM_SLOTSIZE 20000 /* max single variable length */
- X#define CM_PROCESSNAMELENGTH 20
- X#define CM_VARIABLENAMELENGTH 20
- X#define CM_MAXVARIABLENAMELENGTH 20
- X#define CM_MAXPROCESSNAMELENGTH 20
- X#define CM_MAXUSERVARIABLES 100
- X
- X#define E_CMM_DIED -1
- X#define E_CM_INIT_FAILED -2
- X#define E_CM_WRONG_VERSION -100
- END_OF_FILE
- if test 445 -ne `wc -c <'src/cm_constants.h'`; then
- echo shar: \"'src/cm_constants.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_constants.h'
- fi
- if test -f 'src/cm_man.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_man.h'\"
- else
- echo shar: Extracting \"'src/cm_man.h'\" \(1966 characters\)
- sed "s/^X//" >'src/cm_man.h' <<'END_OF_FILE'
- X/*
- X
- XCommon memory is local to the CMM process. It is composed of:
- X
- XAn array of variables. Each variable is a structure with elements such as
- Xa name, type, value, etc.
- X
- XVariable values can be stored in the variable structure if they are small
- X(such as an int) or in a piece of malloc'd memory if they are large (such
- Xas a string).
- X
- XAn array of process descriptors. Each process descriptor is a structure.
- XThe most important element of this structure is the wakeup field. If it is
- Xset, the process should be informed of new variable values.
- X*/
- X
- X#define CM_MANAGER_NAME "cm manager"
- X#define CM_MAXVARIABLES 50
- X#define CM_MAXPROCESSES 20
- X
- X#define is_new(proc,var) (var->role[proc].new)
- X#define is_reader(proc,var) (var->role[proc].reader)
- X#define is_wakeup(proc,var) (var->role[proc].wakeup)
- X#define is_writer(proc,var) (var->role[proc].writer)
- X#define is_nonxwriter(proc,var) (var->role[proc].writer && \
- X var->xwriter != proc)
- X#define is_xwriter(proc,var) (var->xwriter == proc)
- X
- X#define CM_NULL_PROCESS -1
- X
- X/* process descriptors */
- X/* this table is indexed by corresponding file descriptors (or sockets) */
- Xstruct process {
- X char name[CM_PROCESSNAMELENGTH];
- X int inuse;
- X int wakeup; /* per process wakeup */
- X};
- X
- X/* this is how variables are stored internally to the cmm */
- Xstruct variable {
- X char name[CM_VARIABLENAMELENGTH];
- X struct cm_value data; /* data (and size, if necessary) */
- X unsigned long count; /* nth definition of this var */
- X struct timeval timestamp; /* when last written */
- X int command_association;
- X int xwriter; /* name of exclusive writer */
- X int writers; /* number of (any type of) writers */
- X int readers; /* number of readers */
- X struct {
- X unsigned reader : 1; /* reader */
- X unsigned writer : 1; /* writer */
- X unsigned wakeup : 1; /* a-wake me */
- X unsigned new : 1; /* changed but not read */
- X } role[CM_MAXPROCESSES];
- X};
- X
- X/* internal errors specific to CMM */
- X#define E_GET_VARIABLE_NO_SPACE -1
- END_OF_FILE
- if test 1966 -ne `wc -c <'src/cm_man.h'`; then
- echo shar: \"'src/cm_man.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_man.h'
- fi
- if test -f 'src/cm_msg.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_msg.h'\"
- else
- echo shar: Extracting \"'src/cm_msg.h'\" \(938 characters\)
- sed "s/^X//" >'src/cm_msg.h' <<'END_OF_FILE'
- X/*
- X
- XThis file contains definitions relating to message passing between
- Xthe CM manager and user.
- X
- XFollowing is the structure of a message. Unfortunately, this is illegal
- Xbecause "number" is variable as well as the sizeof(slot). This structure
- Xwill be built dynamically when necessary and discarded after the message
- Xhas been used (read or written). In order to make it legal, we will leave
- Xcomment out the "slot" field and read/write that by hand. This hack will
- Xbe used throughout the message code. Yuck.
- X
- X*/
- X
- Xstruct msg {
- X int version; /* version of cmm system */
- X int size; /* size of msg structure itself */
- X int slots; /* number of slots */
- X char name[CM_PROCESSNAMELENGTH];
- X char read_wait; /* TRUE, if sender waiting for an acknowledgement */
- X struct slot data[1]; /* really want [0] */
- X} ;
- X
- X/*
- X
- XEach message is composed of a header. The header includes the process name,
- Xnumber of slots, and the slots themselves.
- X
- X*/
- X
- X
- END_OF_FILE
- if test 938 -ne `wc -c <'src/cm_msg.h'`; then
- echo shar: \"'src/cm_msg.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_msg.h'
- fi
- if test -f 'src/cm_sd.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_sd.h'\"
- else
- echo shar: Extracting \"'src/cm_sd.h'\" \(384 characters\)
- sed "s/^X//" >'src/cm_sd.h' <<'END_OF_FILE'
- X/* cm_sd.h - sized-data structures */
- X
- X/* there is no reason why the items typed as shorts cannot be longer */
- X
- Xtypedef struct cm_value {
- X char *data;
- X unsigned short msize; /* max size of data */
- X unsigned short size; /* size of data used */
- X char mallocable; /* TRUE, if we can free and malloc data */
- X} cm_value;
- X
- Xstruct cm_flattened_data {
- X unsigned short size;
- X char data[1];
- X};
- END_OF_FILE
- if test 384 -ne `wc -c <'src/cm_sd.h'`; then
- echo shar: \"'src/cm_sd.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_sd.h'
- fi
- if test -f 'src/cm_sync.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_sync.h'\"
- else
- echo shar: Extracting \"'src/cm_sync.h'\" \(327 characters\)
- sed "s/^X//" >'src/cm_sync.h' <<'END_OF_FILE'
- X/* cm_sync.h */
- X
- X/* OR together one from first set to one from second set */
- X/* defaults are CM_WAIT|CM_WAIT_FOR_ALL */
- X
- X/* first set of options */
- X#define CM_WAIT 0
- X#define CM_NO_WAIT 1
- X/* second set of options */
- X#define CM_WAIT_FOR_ALL 0
- X#define CM_WAIT_AT_MOST_ONCE 2
- X/* third set of options */
- X#define CM_WAIT_READ 4
- END_OF_FILE
- if test 327 -ne `wc -c <'src/cm_sync.h'`; then
- echo shar: \"'src/cm_sync.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_sync.h'
- fi
- if test -f 'src/cm_time.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_time.c'\"
- else
- echo shar: Extracting \"'src/cm_time.c'\" \(667 characters\)
- sed "s/^X//" >'src/cm_time.c' <<'END_OF_FILE'
- X/* these are utilities for dealing with timeouts */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include "cm_time.h"
- X
- Xstruct timeval cm_period_zero, cm_period_infinite;
- X
- X/* set up some useful constants */
- Xcm_time_init()
- X{
- X cm_time_zero(&cm_period_zero);
- X cm_period_infinite.tv_sec = (u_long)1000000;
- X cm_period_infinite.tv_usec = (long)0;
- X}
- X
- Xcm_time_zero(p)
- Xstruct timeval *p;
- X{
- X p->tv_sec = (u_long)0;
- X p->tv_usec = (long)0;
- X}
- X
- Xcm_time_set(p,s,u)
- Xstruct timeval *p;
- Xint s;
- Xint u;
- X{
- X p->tv_sec = (u_long)s;
- X p->tv_usec = (long)u;
- X}
- X
- Xcm_time_copy(from,to)
- Xstruct timeval *from, *to;
- X{
- X safebcopy((char *)from,(char *)to,sizeof(struct timeval));
- X}
- END_OF_FILE
- if test 667 -ne `wc -c <'src/cm_time.c'`; then
- echo shar: \"'src/cm_time.c'\" unpacked with wrong size!
- fi
- # end of 'src/cm_time.c'
- fi
- if test -f 'src/cm_time.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_time.h'\"
- else
- echo shar: Extracting \"'src/cm_time.h'\" \(116 characters\)
- sed "s/^X//" >'src/cm_time.h' <<'END_OF_FILE'
- Xextern struct timeval cm_period_zero, cm_period_infinite;
- X
- X#define time_now(x) gettimeofday(x,(struct timezone *)0)
- END_OF_FILE
- if test 116 -ne `wc -c <'src/cm_time.h'`; then
- echo shar: \"'src/cm_time.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_time.h'
- fi
- if test -f 'src/cm_util.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_util.c'\"
- else
- echo shar: Extracting \"'src/cm_util.c'\" \(2023 characters\)
- sed "s/^X//" >'src/cm_util.c' <<'END_OF_FILE'
- X/* utilities */
- X
- X#include <stdio.h>
- X#include <strings.h>
- X#include <ctype.h>
- X#include <varargs.h>
- X
- X/* uh-oh, looks like Lisp has a bcopy too! */
- X/* and it doesn't do the same thing as the C bcopy! */
- X/* Now who wants to know how long this took me to find? */
- Xstatic bcopy(s1,s2,length)
- Xchar *s1, *s2;
- Xint length;
- X{
- X while (0 < length--) *s2++ = *s1++;
- X}
- X
- Xvoid
- Xsafebcopy(b1,b2,length)
- Xchar *b1, *b2;
- Xint length;
- X{
- X eprintf(9,"safebcopy(%x,%x,%d)\n",b1,b2,length);
- X if (!b1) {
- X printf("error: bcopy dest is null ptr\n");
- X abort();
- X } else if (!b2) {
- X printf("error: bcopy src is null ptr\n");
- X abort();
- X } else bcopy(b1,b2,length);
- X}
- X
- X/* dump first 20 bytes starting at s in hex */
- Xhex20(s)
- Xchar *s;
- X{
- X int i;
- X for (i=0;i<20;i++) printf("%2x",0xff & s[i]);
- X putchar('\n');
- X}
- X
- X/* dump length bytes worth of s in ascii */
- Xascii_dump(s,length)
- Xchar *s;
- Xint length;
- X{
- X int i;
- X for (i=0;i<length;i++) {
- X if (isascii(s[i]) && isprint(s[i])) {
- X printf(" %c",s[i]);
- X } else {
- X printf(" %02x",0xff & s[i]);
- X }
- X }
- X putchar('/n');
- X}
- X
- Xint cm_debug_level; /* controls how many debugging statements are
- X /* printed. 0 means none, higher numbers mean
- X /* more. */
- X/* levels are:
- X0 nothing
- X1
- X2 msgs send/received
- X3 msgs init, aborted
- X4
- X5 slots composed, decomposed
- X6 slots broken out
- X7
- X8
- X9 bcopy, strcpy, malloc
- X*/
- Xset_cm_debug_level(level)
- Xint level;
- X{
- X cm_debug_level = level;
- X eprintf(1,"cm debug level is %d\n",cm_debug_level);
- X}
- X
- X
- X/* Debugging function, use like printf, but the global var debug_level */
- X/* controls how much is printed */
- X#if 0
- X/* Yes, I know its gross */
- X/*VARARGS2*/
- Xeprintf(level,fmt,v1,v2,v3,v4,v5,v6,v7,v8,v9)
- Xint level;
- Xchar *fmt;
- Xint v1, v2, v3, v4, v5, v6, v7, v8, v9;
- X{
- X if (cm_debug_level >= level) printf(fmt,v1,v2,v3,v4,v5,v6,v7,v8,v9);
- X}
- X#endif
- X
- X/*VARARGS2*/
- Xeprintf(level,fmt,va_alist)
- Xint level;
- Xchar *fmt;
- Xva_dcl
- X{
- X va_list pvar;
- X
- X va_start(pvar);
- X /* & may be incorrect in following statement */
- X if (cm_debug_level >= level) _doprnt(fmt,pvar,stderr);
- X va_end(pvar);
- X}
- END_OF_FILE
- if test 2023 -ne `wc -c <'src/cm_util.c'`; then
- echo shar: \"'src/cm_util.c'\" unpacked with wrong size!
- fi
- # end of 'src/cm_util.c'
- fi
- if test -f 'src/cm_var.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/cm_var.h'\"
- else
- echo shar: Extracting \"'src/cm_var.h'\" \(255 characters\)
- sed "s/^X//" >'src/cm_var.h' <<'END_OF_FILE'
- X/* access types, i.e. roles */
- X#define CM_ROLE_NULL 000
- X#define CM_ROLE_READER 001
- X#define CM_ROLE_WAKEUP 002
- X#define CM_ROLE_NONXWRITER 004
- X#define CM_ROLE_NONEXCLUSIVE_WRITER 004
- X#define CM_ROLE_EXCLUSIVE_WRITER 010
- X#define CM_ROLE_XWRITER 010
- END_OF_FILE
- if test 255 -ne `wc -c <'src/cm_var.h'`; then
- echo shar: \"'src/cm_var.h'\" unpacked with wrong size!
- fi
- # end of 'src/cm_var.h'
- fi
- if test ! -d 'src/franz' ; then
- echo shar: Creating directory \"'src/franz'\"
- mkdir 'src/franz'
- fi
- if test -f 'src/franz/dfuncs.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/franz/dfuncs.h'\"
- else
- echo shar: Extracting \"'src/franz/dfuncs.h'\" \(1350 characters\)
- sed "s/^X//" >'src/franz/dfuncs.h' <<'END_OF_FILE'
- X/* -[Mon Dec 3 16:37:08 1984 by layer]-
- X * dfuncs.h $Locker: $
- X * external function declaration
- X *
- X * $Header: dfuncs.h,v 40.6 85/03/12 12:54:37 layer Exp $
- X *
- X * (c) copyright 1982, Regents of the University of California
- X * Enhancements (c) copyright 1984, Franz Inc., Oakland California
- X */
- X
- Xchar *brk();
- Xchar *pinewstr();
- Xchar *inewstr();
- Xchar *newstr();
- Xchar *sbrk();
- Xchar *xsbrk();
- Xchar *ysbrk();
- Xint csizeof();
- Xlispval Iget();
- Xlispval Imakeht();
- Xlispval Imkrtab();
- Xlispval Iputprop();
- Xlispval Istsrch();
- Xlispval Lfuncal();
- Xlispval Lnegp();
- Xlispval Lread();
- Xlispval Lsub();
- Xlispval copval();
- Xlispval csegment();
- Xlispval error();
- Xlispval errorh();
- Xlispval errorh1();
- Xlispval errorh2();
- Xlispval eval();
- Xlispval gc();
- Xlispval getatom();
- Xlispval inewatom();
- Xlispval inewint();
- Xlispval inewval();
- Xlispval matom();
- Xlispval mfun();
- Xlispval mstr();
- Xlispval newarray();
- Xlispval newdot();
- Xlispval newdoub();
- Xlispval newfunct();
- Xlispval newint();
- Xlispval newsdot();
- Xlispval newval();
- Xlispval newhunk();
- Xlispval pnewdot();
- Xlispval pnewdb();
- Xlispval pnewhunk();
- Xlispval pnewint();
- Xlispval pnewsdot();
- Xlispval pnewval();
- Xlispval popnames();
- Xlispval r();
- Xlispval ratomr();
- Xlispval readr();
- Xlispval readrx();
- Xlispval readry();
- Xlispval typefrob();
- Xlispval typred();
- Xlispval unprot();
- Xlispval verify();
- Xstruct atom *makeatom();
- Xstruct atom *newatom();
- END_OF_FILE
- if test 1350 -ne `wc -c <'src/franz/dfuncs.h'`; then
- echo shar: \"'src/franz/dfuncs.h'\" unpacked with wrong size!
- fi
- # end of 'src/franz/dfuncs.h'
- fi
- if test -f 'src/franz/lconf.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/franz/lconf.h'\"
- else
- echo shar: Extracting \"'src/franz/lconf.h'\" \(16 characters\)
- sed "s/^X//" >'src/franz/lconf.h' <<'END_OF_FILE'
- X#define sun_4_2
- END_OF_FILE
- if test 16 -ne `wc -c <'src/franz/lconf.h'`; then
- echo shar: \"'src/franz/lconf.h'\" unpacked with wrong size!
- fi
- # end of 'src/franz/lconf.h'
- fi
- if test -f 'src/franz/ltypes.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/franz/ltypes.h'\"
- else
- echo shar: Extracting \"'src/franz/ltypes.h'\" \(1031 characters\)
- sed "s/^X//" >'src/franz/ltypes.h' <<'END_OF_FILE'
- X/* -[Wed May 15 10:14:01 1985 by layer]-
- X * ltypes.h $Locker: $
- X * lisp data type defs
- X *
- X * $Header: ltypes.h,v 40.6 85/05/16 03:58:00 smh Exp $
- X *
- X * (c) copyright 1982, Regents of the University of California
- X * Enhancements (c) copyright 1984, Franz Inc., Oakland California
- X */
- X
- X/* type flags */
- X
- X#define UNBO -1
- X#define STRNG 0
- X#define ATOM 1
- X#define INT 2
- X#define DTPR 3
- X#define DOUB 4
- X#define BCD 5
- X#define PORT 6
- X#define ARRAY 7
- X#define OTHER 8
- X#define SDOT 9
- X#define VALUE 10
- X
- X#define HUNK2 11 /* The hunks */
- X#define HUNK4 12
- X#define HUNK8 13
- X#define HUNK16 14
- X#define HUNK32 15
- X#define HUNK64 16
- X#define HUNK128 17
- X
- X#define VECTOR 18
- X#define VECTORI 19
- X
- X#define NUMSPACES (VECTORI + 1)
- X
- X#define HUNKP(a1) ((TYPE(a1) >= HUNK2) & (TYPE(a1) <= HUNK128))
- X
- X#define HASHTP(p) ((p)->v.vector[VPropOff] == hasht_atom)
- X#define PACKAGEP(p) ((p)->v.vector[VPropOff] == pkg_atom)
- X#define INSTANCEP(p) ((TYPE((p)->v.vector[VPropOff]) == VECTOR) && \
- X ((p)->v.vector[VPropOff]->v.vector[VPROPOFF] == \
- X flavor))
- X
- END_OF_FILE
- if test 1031 -ne `wc -c <'src/franz/ltypes.h'`; then
- echo shar: \"'src/franz/ltypes.h'\" unpacked with wrong size!
- fi
- # end of 'src/franz/ltypes.h'
- fi
- if test -f 'src/franz/module.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/franz/module.h'\"
- else
- echo shar: Extracting \"'src/franz/module.h'\" \(1662 characters\)
- sed "s/^X//" >'src/franz/module.h' <<'END_OF_FILE'
- X/* -[Sat Jun 2 08:09:36 1984 by jkf]-
- X * module.h $Locker: $
- X *
- X * module interface includes
- X *
- X * $Header: module.h,v 40.2 84/11/13 14:23:46 schlafly Exp $
- X *
- X * (c) copyright 1984, Franz Inc., Oakland California
- X */
- X
- X/*
- X * All C coded modules will contain a VERSION
- X * header in which the rcs header is stored
- X */
- X
- X#ifndef lint
- X#define VERSION(s) static char *rcsid = s
- X#else
- X#define VERSION(s)
- X#endif
- X
- X
- X/*
- X * All variables are either private in the module or else are
- X * shared among 2 or more files.
- X * Private variables are declared Private inside the file.
- X * Non-private variables are either declared Public in a .h file which
- X * all files that wish to reference that variable must include,
- X * or are declared Export in a C (non-header) file. C files wishing
- X * to reference those variables declare the variable Import.
- X *
- X *
- X * Private corresponds to 'static' in C, although it usually isn't a good
- X * idea to declare variables or functions to be static if you want to debug
- X * the code with something like adb.
- X * Export corresponds to '' (nothing), and Import to 'extern'.
- X * Public corresponds to 'extern' in C, although there must be one file
- X * in which the 'extern' isn't declared. To order to strip the extern,
- X * the macro DefineData should be set before including files.
- X *
- X * Public should be used instead of Import and Export since it assures
- X * that every module gets the same declaration. However it does require
- X * a .h file, and this may be too much effort for one or two variables.
- X *
- X */
- X
- X#define Private static
- X#define Export
- X#define Import extern
- X
- X#ifdef DefineData
- X# define Public
- X#else
- X# define Public extern
- X#endif
- END_OF_FILE
- if test 1662 -ne `wc -c <'src/franz/module.h'`; then
- echo shar: \"'src/franz/module.h'\" unpacked with wrong size!
- fi
- # end of 'src/franz/module.h'
- fi
- if test -f 'src/franz/public.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/franz/public.h'\"
- else
- echo shar: Extracting \"'src/franz/public.h'\" \(1909 characters\)
- sed "s/^X//" >'src/franz/public.h' <<'END_OF_FILE'
- X/* -[Tue May 21 17:05:40 1985 by layer]-
- X * public.h $Locker: $
- X *
- X * definition for Public data objects which all files are permitted
- X * to look at. [These are the very public data objects]
- X *
- X * $Header: public.h,v 40.5 85/05/21 17:24:04 layer Exp $
- X *
- X *
- X * (c) copyright 1984, Franz Inc., Oakland California
- X */
- X
- X#ifdef apollo
- Xextern
- X#else
- XPublic
- X#endif
- Xstruct nament *bnp; /* first free bindstack entry */
- XPublic struct nament *bnplim, /* limit of bindstack */
- X *orgbnp; /* base of the bindstack */
- X
- X
- X#ifdef NPINREG
- XImport
- X#else
- X#ifdef apollo
- Xextern
- X#else
- XPublic
- X#endif apollo
- X#endif NPINREG
- X struct argent *lbot, /* base of arguments to function */
- X *np; /* first free namestack entry */
- X
- XPublic struct argent *nplim, /* one above limit of namestack */
- X *orgnp; /* first slot in the namestack */
- X
- X#ifdef apollo
- Xextern
- X#else
- XPublic
- X#endif apollo
- X word retval; /* used by each error/prog call */
- X /* retval could be an int */
- X#ifdef apollo
- Xextern
- X#else
- XPublic
- X#endif apollo
- Xlispval lispretval; /* used by non-local go */
- X
- XPublic lispval datalim; /* limit of valid data area */
- X
- XPublic lispval vtemp; /* used in a few macros as a temp */
- XPublic long sigintcnt; /* count of interrupts since processed */
- X /* sigintcnt could be an int */
- X
- XImport char typetable[]; /* one byte per page */
- X
- X#ifdef MVR
- X/* Stuff having to do with Multiple Values */
- X#ifdef apollo
- Xextern
- X#else
- XPublic
- X#endif apollo
- Xint nmvr; /* # of multiple values being returned less 1 */
- XImport int mmvr; /* Max # of multiple values possibly returned*/
- X#ifdef apollo
- Xextern
- X#else
- XPublic
- X#endif apollo
- Xlispval *mvals; /* pointer to a static storage area for them */
- XPublic lispval *mvalsMMVR; /* pointer to end of storage area for them */
- X#define clrnmv() (nmvr = 0);
- X#endif MVR
- X
- X#ifdef Savelisp
- XPublic lispval relvectors; /* for save/restorelisp */
- X#endif Savelisp
- END_OF_FILE
- if test 1909 -ne `wc -c <'src/franz/public.h'`; then
- echo shar: \"'src/franz/public.h'\" unpacked with wrong size!
- fi
- # end of 'src/franz/public.h'
- fi
- if test -f 'src/man_put_slot.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/man_put_slot.c'\"
- else
- echo shar: Extracting \"'src/man_put_slot.c'\" \(1541 characters\)
- sed "s/^X//" >'src/man_put_slot.c' <<'END_OF_FILE'
- X/*
- X
- XThese routines build slots for the cmm. These slots are placed into a
- Xmsg structure and sent to the user.
- X
- X*/
- X
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include "cm_constants.h"
- X#include "cm_sd.h"
- X#include "cm_slot.h" /* definitions of slot structures */
- X#include "cm_bytestuff.h"
- X
- Xextern struct msg *omsg; /* this is soooo... messy */
- X
- Xput_slot_read_response(m,name,count,timestamp,cmd,data)
- Xstruct msg *m;
- Xchar *name;
- Xunsigned long count;
- Xstruct timeval *timestamp;
- Xint cmd;
- Xcm_value *data;
- X{
- X struct big_slot s;
- X unsigned int size;
- X
- X init_slot(&s,name,CM_SLOT_READ_RESPONSE);
- X size = align(sizeof(struct slot_hdr));
- X size += align(sizeof(struct slot_read_response_hdr));
- X s.subslot.read_response.srr_count = count;
- X cm_time_copy(timestamp,&s.subslot.read_response.srr_timestamp);
- X s.subslot.read_response.srr_command_association = cmd;
- X size += cm_sd_to_flat(data,&s.subslot.read_response.fdata);
- X finish_slot(m,&s,size);
- X}
- X
- X/* error slots should never be generated by the user since infinite loops */
- X/* could result between the user and cmm sending each other back error slots */
- Xput_slot_error(m,name,type,string)
- Xstruct msg *m;
- Xchar *name;
- Xint type;
- Xchar *string;
- X{
- X struct big_slot s;
- X unsigned int size;
- X
- X fprintf(stdout,"slot error in <%s> type %d - %s\n",name,type,string);
- X
- X init_slot(&s,name,CM_SLOT_ERROR);
- X size = align(sizeof(struct slot_hdr));
- X size += align(sizeof(struct slot_error_hdr));
- X size += strlen(string) + 1;
- X s.subslot.error.se_type = type;
- X strcpy(s.subslot.error.msg,string);
- X finish_slot(m,&s,size);
- X}
- END_OF_FILE
- if test 1541 -ne `wc -c <'src/man_put_slot.c'`; then
- echo shar: \"'src/man_put_slot.c'\" unpacked with wrong size!
- fi
- # end of 'src/man_put_slot.c'
- fi
- if test -f 'src/msg.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/msg.c'\"
- else
- echo shar: Extracting \"'src/msg.c'\" \(966 characters\)
- sed "s/^X//" >'src/msg.c' <<'END_OF_FILE'
- X/* msg.c */
- X
- X#include <sys/time.h>
- X#include "cm_constants.h"
- X#include "cm_sd.h"
- X#include "cm_slot.h"
- X#include "cm_msg.h"
- X#include "cm_bytestuff.h"
- X
- Xextern int cm_debug_level;
- X
- X/* returns NULL if no more slots */
- Xstruct slot *
- Xnextslot(m,s)
- Xstruct msg *m;
- Xstruct slot *s;
- X{
- X struct slot *next;
- X
- X next = (struct slot *)byteadd(s,s->s_size);
- X if (next >= (struct slot *)byteadd(m,m->size))
- X return((struct slot *)0);
- X return(next);
- X}
- X
- Xprint_msg(m)
- Xstruct msg *m;
- X{
- X struct slot *s;
- X
- X eprintf(3,"msg header:");
- X eprintf(3," size = %d",m->size);
- X eprintf(3," slots = %d",m->slots);
- X eprintf(3," name = %s",m->name);
- X eprintf(3," read_wait = %d\n",m->read_wait);
- X for (s=m->data;s;s=nextslot(m,s)) {
- X eprintf(5,"slot: name = %s",s->s_name);
- X eprintf(5," &slot = %x",s);
- X eprintf(5," size = %d\n",s->s_size);
- X if (s->s_size == 0) {
- X eprintf(5,"0 length slot encountered in print_msg\n");
- X break;
- X }
- X }
- X if (cm_debug_level >= 10) ascii_dump((char *)m,m->size);
- X}
- X
- END_OF_FILE
- if test 966 -ne `wc -c <'src/msg.c'`; then
- echo shar: \"'src/msg.c'\" unpacked with wrong size!
- fi
- # end of 'src/msg.c'
- fi
- if test -f 'src/name.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/name.c'\"
- else
- echo shar: Extracting \"'src/name.c'\" \(216 characters\)
- sed "s/^X//" >'src/name.c' <<'END_OF_FILE'
- X/* set_cm_process_name.c */
- X
- X#include <stdio.h>
- X#include "cm_constants.h"
- X
- Xchar cm_process_name[CM_PROCESSNAMELENGTH];
- X
- Xset_cm_process_name(name)
- Xchar *name;
- X{
- X strncpy(cm_process_name,name,CM_PROCESSNAMELENGTH);
- X}
- X
- END_OF_FILE
- if test 216 -ne `wc -c <'src/name.c'`; then
- echo shar: \"'src/name.c'\" unpacked with wrong size!
- fi
- # end of 'src/name.c'
- fi
- if test -f 'src/put_slot.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/put_slot.c'\"
- else
- echo shar: Extracting \"'src/put_slot.c'\" \(2010 characters\)
- sed "s/^X//" >'src/put_slot.c' <<'END_OF_FILE'
- X/*
- X
- XThese are some utility routines for building slots. These slots
- Xare placed in a msg structure and sent from the user to the cmm or vice-versa.
- X
- X*/
- X
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include <strings.h>
- X#include "cm_constants.h"
- X#include "cm_sd.h"
- X#include "cm_slot.h" /* definitions of slot structures */
- X#include "cm_msg.h" /* definitions of msg structures */
- X#include "cm_bytestuff.h"
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- Xextern char cm_process_name[];
- X
- Xint /* returns # of bytes written into msg structure */
- Xfinish_slot(m,slot,slotsize)
- Xstruct msg *m;
- Xstruct slot *slot;
- Xunsigned int slotsize;
- X{
- X if (m->size + slotsize > CM_MSGSIZE) {
- X fprintf(stderr,"too much data for msg!!\n");
- X fprintf(stderr,"output msg size = %d slotsize = %d CM_MSGSIZE = %d\n",
- X m->size,slotsize,CM_MSGSIZE);
- X return(0);
- X }
- X /* copy slot into msg after previous slot */
- X slot->s_size = slotsize; /* this is not aligned, right? */
- X eprintf(10,"finish_slot: bcopying slot (size = %d) into msg\n",
- X slot->s_size);
- X safebcopy((char *)slot,(char *)byteadd(m,m->size),slotsize);
- X eprintf(10,"finish_slot: after bcopy, message slot size = %d\n",
- X ((struct slot *)byteadd(m,m->size))->s_size);
- X m->slots++;
- X m->size += align(slotsize);
- X return(align(slotsize));
- X}
- X
- Xinit_msg(m)
- Xstruct msg *m;
- X{
- X m->version = CMM_VERSION;
- X m->slots = 0;
- X m->read_wait = FALSE;
- X strcpy(m->name,cm_process_name);
- X m->size = sizeof(struct msg) - sizeof(struct slot);
- X}
- X
- X/*
- Xinit_slot does the following:
- X sets the slot name and type
- X*/
- Xinit_slot(s,name,type)
- Xstruct slot *s;
- Xchar *name;
- Xint type;
- X{
- X s->s_type = type;
- X strcpy(s->s_name,name);
- X}
- X
- Xchar *
- Xcm_slot_type(t)
- Xint t;
- X{
- X switch (t) {
- X case CM_SLOT_NULL: return("null slot type");
- X case CM_SLOT_DECLARE: return("declare");
- X case CM_SLOT_WRITE: return("write");
- X case CM_SLOT_READ: return("read");
- X case CM_SLOT_READ_RESPONSE: return("read response");
- X case CM_SLOT_ERROR: return("error");
- X case CM_SLOT_UNDECLARE: return("undeclare");
- X default: return("unknown slot type");
- X }
- X}
- END_OF_FILE
- if test 2010 -ne `wc -c <'src/put_slot.c'`; then
- echo shar: \"'src/put_slot.c'\" unpacked with wrong size!
- fi
- # end of 'src/put_slot.c'
- fi
- if test -f 'src/server1y.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/server1y.c'\"
- else
- echo shar: Extracting \"'src/server1y.c'\" \(652 characters\)
- sed "s/^X//" >'src/server1y.c' <<'END_OF_FILE'
- X/* server1y.c
- X
- XThis process prints the latest values of variables a_var and b_var when
- Xthe user presses return.
- X
- X*/
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xcm_value a_val = {0,0,0,1}, b_val = {0,0,0,1};
- X
- Xmain()
- X{
- X cm_variable *a_var, *b_var;
- X
- X if (0>cm_init("press return",0,0)) exit(-1);
- X
- X if (!(a_var = cm_declare("a_var",CM_ROLE_READER)))
- X exit(-1);
- X if (!(b_var = cm_declare("b_var",CM_ROLE_READER)))
- X exit(-1);
- X
- X printf("press return for latest values\n");
- X for (;;) {
- X getchar();
- X cm_sync(CM_WAIT_READ);
- X cm_get_value(a_var,&a_val);
- X printf("a_var: %s\n",a_val.data);
- X cm_get_value(b_var,&b_val);
- X printf("b_var: %s\n",b_val.data);
- X }
- X}
- END_OF_FILE
- if test 652 -ne `wc -c <'src/server1y.c'`; then
- echo shar: \"'src/server1y.c'\" unpacked with wrong size!
- fi
- # end of 'src/server1y.c'
- fi
- if test -f 'src/server1z.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/server1z.c'\"
- else
- echo shar: Extracting \"'src/server1z.c'\" \(610 characters\)
- sed "s/^X//" >'src/server1z.c' <<'END_OF_FILE'
- X/* server1.c
- XThis process, s, prints the latest values of variables a_var and b_var
- X*/
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xcm_value a_val = {0,0,0,1}, b_val = {0,0,0,1};
- X
- Xmain()
- X{
- X cm_variable *a_var, *b_var;
- X
- X if (0>cm_init("s",0,0)) exit(-1);
- X
- X if (!(a_var = cm_declare("a_var",CM_ROLE_READER|CM_ROLE_WAKEUP)))
- X exit(-1);
- X if (!(b_var = cm_declare("b_var",CM_ROLE_READER|CM_ROLE_WAKEUP)))
- X exit(-1);
- X
- X for (;;) {
- X cm_sync(CM_WAIT_AT_MOST_ONCE);
- X if (cm_get_new_value(a_var,&a_val))
- X printf("a_var: %s\n",a_val.data);
- X if (cm_get_new_value(b_var,&b_val))
- X printf("b_var: %s\n",b_val.data);
- X }
- X}
- END_OF_FILE
- if test 610 -ne `wc -c <'src/server1z.c'`; then
- echo shar: \"'src/server1z.c'\" unpacked with wrong size!
- fi
- # end of 'src/server1z.c'
- fi
- if test -f 'src/server2.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/server2.c'\"
- else
- echo shar: Extracting \"'src/server2.c'\" \(823 characters\)
- sed "s/^X//" >'src/server2.c' <<'END_OF_FILE'
- X/* all this server does is print out whatever its given */
- X
- X/* Note, this has not been converted over to use cmm v7!!! */
- X
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X cm_variable *i_var, *d_var, *s_var;
- X char s_val[1000];
- X int i_val;
- X double d_val;
- X
- X if (argc>1) printf("going to host %s for cmm\n",argv[1]);
- X if (0 > cm_init("printer",(argc>1?argv[1]:(char *)0),0)) exit(-1);
- X
- X i_var = cm_declare("i_var",CM_ROLE_READER | CM_ROLE_WAKEUP);
- X d_var = cm_declare("d_var",CM_ROLE_READER);
- X s_var = cm_declare("s_var",CM_ROLE_READER);
- X
- X while (TRUE) {
- X if (0 > cm_sync(CM_WAIT_AT_MOST_ONCE)) return;
- X cm_get_value(i_var,&i_val);
- X printf("i_var = %d\n",i_val);
- X cm_get_value(d_var,&d_val);
- X printf("d_var = %g\n",d_val);
- X cm_get_value(s_var,s_val);
- X printf("s_var = %s\n",s_val);
- X }
- X}
- END_OF_FILE
- if test 823 -ne `wc -c <'src/server2.c'`; then
- echo shar: \"'src/server2.c'\" unpacked with wrong size!
- fi
- # end of 'src/server2.c'
- fi
- if test -f 'src/server8a.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/server8a.c'\"
- else
- echo shar: Extracting \"'src/server8a.c'\" \(388 characters\)
- sed "s/^X//" >'src/server8a.c' <<'END_OF_FILE'
- X/* server8a.c - constant wait on common memory to test that cmm doesn't */
- X/* blow up when we die and it is writing to us (SIGPIPE) */
- X
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xcm_variable *variable;
- X
- Xmain()
- X{
- X if (0>cm_init("constant reader SIGPIPE",0,0)) exit(-1);
- X
- X if (!(variable = cm_declare("variable",CM_ROLE_READER|CM_ROLE_WAKEUP))) exit(-1);
- X
- X while (1) {
- X cm_sync(CM_WAIT);
- X }
- X}
- END_OF_FILE
- if test 388 -ne `wc -c <'src/server8a.c'`; then
- echo shar: \"'src/server8a.c'\" unpacked with wrong size!
- fi
- # end of 'src/server8a.c'
- fi
- if test -f 'src/server8b.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/server8b.c'\"
- else
- echo shar: Extracting \"'src/server8b.c'\" \(366 characters\)
- sed "s/^X//" >'src/server8b.c' <<'END_OF_FILE'
- X/* server8b.c - receive updates from common memory but do not read() */
- X/* see if cmm eventually hangs on write() */
- X
- X#include <sys/time.h>
- X#include "cm.h"
- X
- Xcm_variable *variable;
- X
- Xmain()
- X{
- X if (0>cm_init("constant reader hang",0,0)) exit(-1);
- X
- X if (!(variable = cm_declare("variable",CM_ROLE_READER|CM_ROLE_WAKEUP))) exit(-1);
- X
- X cm_sync(CM_NO_WAIT);
- X sigpause();
- X}
- END_OF_FILE
- if test 366 -ne `wc -c <'src/server8b.c'`; then
- echo shar: \"'src/server8b.c'\" unpacked with wrong size!
- fi
- # end of 'src/server8b.c'
- fi
- if test -f 'src/usr_get_slot.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/usr_get_slot.c'\"
- else
- echo shar: Extracting \"'src/usr_get_slot.c'\" \(1508 characters\)
- sed "s/^X//" >'src/usr_get_slot.c' <<'END_OF_FILE'
- X/*
- X
- Xthese functions are used by the user to read and process information from
- Xincoming slots
- X
- X*/
- X
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include "cm_constants.h"
- X#include "cm_sd.h"
- X#include "cm_interface.h"
- X#include "cm_slot.h"
- X
- Xcm_variable *get_variable();
- X
- Xuser_decode_slot(s)
- Xstruct slot *s;
- X{
- X int rc = 0;
- X
- X switch (s->s_type) {
- X case CM_SLOT_READ_RESPONSE:
- X rc = get_slot_read_response(s->s_name,
- X &s->subslot.read_response);
- X break;
- X case CM_SLOT_ERROR:
- X rc = get_slot_error(s->s_name,&s->subslot.error);
- X break;
- X default:
- X fprintf(stderr,"user_decode_slot: unknown slot type (%d)...msg aborted\n",s->s_type);
- X rc = E_CM_GET_SLOT_UNKNOWN_SLOT_TYPE;
- X break;
- X }
- X return(rc);
- X}
- X
- X/* returns 0 if ok, negative if problem decoding slot */
- Xint
- Xget_slot_error(name,s)
- Xchar *name;
- Xstruct slot_error *s;
- X{
- X fprintf(stderr,"CMM: error processing variable <%s> - %s\n",name,
- X s->msg);
- X /* isn't there a "type" field in the error subslot, too? */
- X return(0);
- X}
- X
- X/* 0 if ok, negative if problem decoding slot */
- Xint
- Xget_slot_read_response(name,s)
- Xchar *name;
- Xstruct slot_read_response *s;
- X{
- X int rc;
- X cm_variable *v;
- X
- X if (!(v = get_variable(name))) {
- X fprintf(stderr,"get_slot_read_response: <%s> unknown (sent from cm)\n",v->name);
- X return(E_CM_GET_SLOT_GET_VARIABLE);
- X }
- X
- X if (0 > cm_flat_to_sd(&s->fdata,&v->data))
- X return(E_CM_GET_SLOT_FLAT_TO_SD);
- X v->count = s->srr_count;
- X v->command_association = s->srr_command_association;
- X cm_time_copy(&s->srr_timestamp,&v->timestamp);
- X return(0);
- X}
- X
- END_OF_FILE
- if test 1508 -ne `wc -c <'src/usr_get_slot.c'`; then
- echo shar: \"'src/usr_get_slot.c'\" unpacked with wrong size!
- fi
- # end of 'src/usr_get_slot.c'
- fi
- if test -f 'src/usr_put_slot.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/usr_put_slot.c'\"
- else
- echo shar: Extracting \"'src/usr_put_slot.c'\" \(2058 characters\)
- sed "s/^X//" >'src/usr_put_slot.c' <<'END_OF_FILE'
- X
- X/*
- X
- XThese routines build slots for the user. These slots are placed into a
- Xmsg structure and sent to the cmm. The all return 0 for failure, or a
- Xpositive number indicating the number of bytes in the slot.
- X
- X*/
- X
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include "cm_constants.h"
- X#include "cm_sd.h"
- X#include "cm_slot.h"
- X#include "cm_msg.h"
- X#include "cm_bytestuff.h"
- X#include "cm_interface.h"
- X
- X/* this indicates that the user wants the cmm to send back the latest value */
- X/* of all variables */
- Xput_slot_read(m)
- Xstruct msg *m;
- X{
- X struct slot s;
- X unsigned int size;
- X
- X init_slot(&s,"read all",CM_SLOT_READ);
- X size = align(sizeof(struct slot_hdr));
- X/* size += align(sizeof(struct slot_read));*/
- X return(finish_slot(m,&s,size));
- X}
- X
- Xint /* returns size of data written in msg */
- Xput_slot_write(m,name,data,cmd)
- Xstruct msg *m;
- Xchar *name;
- Xcm_value *data;
- Xint cmd;
- X{
- X struct big_slot s;
- X unsigned int size;
- X
- X init_slot((struct slot *)&s,name,CM_SLOT_WRITE);
- X size = align(sizeof(struct slot_hdr));
- X size += align(sizeof(struct slot_write_hdr));
- X s.subslot.write.sw_command_association = cmd;
- X size += cm_sd_to_flat(data,&s.subslot.write.fdata);
- X return(finish_slot(m,(struct slot *)&s,size));
- X}
- X
- Xint
- Xput_slot_declare(m,name,role,cmd_assoc)
- Xstruct msg *m;
- Xchar *name;
- Xstruct usr_var_role *role;
- Xint cmd_assoc;
- X{
- X struct slot s;
- X unsigned int size;
- X
- X init_slot(&s,name,CM_SLOT_DECLARE);
- X size = align(sizeof(struct slot_hdr));
- X size += align(sizeof(struct slot_declare));
- X /* could do some checking on the following */
- X s.subslot.declare.role.reader = role->reader;
- X s.subslot.declare.role.wakeup = role->wakeup;
- X s.subslot.declare.role.xwriter = role->xwriter;
- X s.subslot.declare.role.nonxwriter = role->nonxwriter;
- X s.subslot.declare.command_association = cmd_assoc;
- X return(finish_slot(m,&s,size));
- X}
- X
- Xint
- Xput_slot_undeclare(m,name)
- Xstruct msg *m;
- Xchar *name;
- X{
- X struct slot s;
- X unsigned int size;
- X
- X init_slot(&s,name,CM_SLOT_UNDECLARE);
- X size = align(sizeof(struct slot_hdr));
- X/* size += align(sizeof(struct slot_undeclare));*/
- X return(finish_slot(m,&s,size));
- X}
- END_OF_FILE
- if test 2058 -ne `wc -c <'src/usr_put_slot.c'`; then
- echo shar: \"'src/usr_put_slot.c'\" unpacked with wrong size!
- fi
- # end of 'src/usr_put_slot.c'
- fi
- if test -f 'src/usr_var.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/usr_var.c'\"
- else
- echo shar: Extracting \"'src/usr_var.c'\" \(2280 characters\)
- sed "s/^X//" >'src/usr_var.c' <<'END_OF_FILE'
- X/* usr_var.c - utility functions for user only! */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <strings.h>
- X
- X#include "cm_constants.h"
- X#include "cm_sd.h"
- X#include "cm_interface.h"
- X
- Xcm_variable cm_variables[CM_MAXUSERVARIABLES];
- X
- Xcm_variable *
- Xget_variable(name)
- Xchar *name;
- X{
- X int i;
- X
- X eprintf(10,"entering get_variable(%s)\n",name);
- X for (i=0;i<CM_MAXUSERVARIABLES;i++) {
- X /* create it if we come to an empty variable */
- X if (!cm_variables[i].status.inuse) {
- X eprintf(10,"get_variable: found empty variable slot\n");
- X strcpy(cm_variables[i].name,name);
- X cm_sd_clear(&cm_variables[i].data);
- X cm_variables[i].role.reader = 0;
- X cm_variables[i].role.nonxwriter = 0;
- X cm_variables[i].role.wakeup = 0;
- X cm_variables[i].role.xwriter = 0;
- X cm_variables[i].old_count = 0;
- X cm_variables[i].count = 0;
- X cm_variables[i].command_association = 0;
- X cm_time_zero(&cm_variables[i].timestamp);
- X cm_variables[i].status.inuse = TRUE;
- X cm_variables[i].status.written = FALSE;
- X cm_variables[i].status.declared = FALSE;
- X return(&cm_variables[i]);
- X }
- X /* found an old definition */
- X if (!(strcmp(cm_variables[i].name,name))) {
- X eprintf(10,"get_variable() found old defn\n");
- X return(&cm_variables[i]);
- X }
- X }
- X /* no old definition and no space for a new one!!!! */
- X return(NULL);
- X}
- X
- X/*
- XThe following function allows the user to step through all the common
- Xmemory values, for example, to see if any have changed. If v is NULL,
- Xthe first value is returned. If no more cm_variables are in use, NULL is
- Xreturned.
- X
- XThis function is also used by the common memory system itself, as it
- Xhides the implementation of the user cm_variables as a large array.
- XPresumably, it will be changed to have a hash index in the future
- Xfor speed.
- X*/
- Xcm_variable *
- Xnext_user_variable(v)
- Xcm_variable *v; /* if NULL, start from the beginning */
- X{
- X if (v == 0) v = cm_variables; /* reinitialize */
- X else v++; /* next one */
- X
- X for (;v<&cm_variables[CM_MAXUSERVARIABLES];v++) {
- X if (v->status.inuse) return(v);
- X }
- X return((cm_variable *)NULL);
- X}
- END_OF_FILE
- if test 2280 -ne `wc -c <'src/usr_var.c'`; then
- echo shar: \"'src/usr_var.c'\" unpacked with wrong size!
- fi
- # end of 'src/usr_var.c'
- fi
- if test ! -d 'stream' ; then
- echo shar: Creating directory \"'stream'\"
- mkdir 'stream'
- fi
- if test -f 'stream/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stream/Makefile'\"
- else
- echo shar: Extracting \"'stream/Makefile'\" \(932 characters\)
- sed "s/^X//" >'stream/Makefile' <<'END_OF_FILE'
- XCOMMON = stream.o sized_io.o
- XOFILES = $(COMMON) reader.o writer.o
- XHFILES = inet.h
- XCFLAGS =
- X#CFLAGS = -g -DDEBUG
- XLIB = libstream.a
- X
- X# for testing purposes
- X
- Xtest: libstream.a reader writer
- X
- Xlibstream.a: stream.o sized_io.o
- X ar cr libstream.a `lorder $(COMMON) | tsort`
- X ranlib libstream.a
- X
- Xcleanup:
- X rm $(OFILES) libstream.a
- X
- Xinstall: libstream.a makedirs
- X cp $(HFILES) /usr/local/include/inet/stream
- X cp libstream.a /usr/local/lib
- X cp stream.3 /usr/local/man/manl/sized_io.l
- X
- Xmakedirs: /usr/local/include/inet /usr/local/include/inet/stream
- X
- X/usr/local/include/inet:
- X mkdir /usr/local/include/inet
- X
- X/usr/local/include/inet/stream:
- X mkdir /usr/local/include/inet/stream
- X
- Xlint:
- X lint -u stream.c _sized_io.c
- X
- Xlintc:
- X lint -Cstream stream.c _sized_io.c
- X su -c "mv llib-lstream.ln /usr/lib/lint" -f
- X
- Xreader: reader.o $(COMMON)
- X cc $(CFLAGS) -o reader reader.o $(LIB)
- X
- Xwriter: writer.o $(COMMON)
- X cc $(CFLAGS) -o writer writer.o $(LIB)
- END_OF_FILE
- if test 932 -ne `wc -c <'stream/Makefile'`; then
- echo shar: \"'stream/Makefile'\" unpacked with wrong size!
- fi
- # end of 'stream/Makefile'
- fi
- if test -f 'stream/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stream/README'\"
- else
- echo shar: Extracting \"'stream/README'\" \(2493 characters\)
- sed "s/^X//" >'stream/README' <<'END_OF_FILE'
- XThis package provides a quick-and-easy means of providing reliable
- Xand large-packet communication between processes.
- X
- XIt is especially nice because initport() does all the hard work of
- Xinitializing TCP connections, and select_server_stream() does the
- Xhard work of connecting processes to each other.
- X
- XTo install, type
- X
- X make install
- X
- XTo test, type
- X
- X make test
- X reader
- X writer (in different window)
- X writer (in yet another window)
- X writer (in yet ...)
- X and so on.
- X
- X
- Xreader and writer are two programs that should communicate with
- Xeach other. Type things into any of the writers and reader will
- Xprint it out prefaced by the file descriptor the data came in on.
- X
- XBugs and problems to Don Libes
- XNational Bureau of Standards
- XBldg 220, Rm A-127
- XGaithersburg, MD 20899
- X(301) 975-3535
- X
- X
- XSYNOPSIS
- X
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <inet.h>
- X
- X cc [options] [files] sized_io.o stream.o
- X
- XDESCRIPTION
- X
- XThis package implements packet or stream IO between a server process and
- Xa number of client processes, using the TCP/IP (stream) facilities.
- X
- XA client uses the call:
- X
- X s = initport(PORT_NUMBER(XXX),CLIENT,SOCK_STREAM);
- X
- Xs is the server's data socket and is used as a file descriptor in further
- Xcommunication. The port may be specified by name (PORT_NAME("foo")), if it
- Xis registered.
- X
- XSimilarly, the server uses the following call:
- X
- X s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM);
- X
- Xs is the server's connection socket. To receive data or connections, the
- Xserver calls select_server_stream().
- X
- X client = select_server_stream(s,&fds);
- X
- XThis returns a file descriptor corresponding to a client, when a client has
- Xsent a message to the server. It handles initial connections as well as
- Xclient deaths. s is the server's connection socket that was returned by
- Xinitport(). fds is an int used by select...() for storing a bit string
- Xcorresponding to client sockets. Initialize it to 0, and don't mess with it
- Xafter that.
- X
- XTo use the file descriptors in a stream-oriented manner, use read() and
- Xwrite(). To use the file descriptors in a packet-oriented manner, use
- Xsized_read() and sized_write(). The sized...() calls read and write one
- Xpacket at a time, while packet boundaries are ignored in read() and write().
- X
- X cc = sized_read(fd,buffer,maxsize)
- X cc = sized_write(fd,buffer,size)
- X
- XThe arguments for sized_read() and sized_write() are very similar to read()
- Xand write(). The only difference is that in sized_read(), maxsize is the
- Xmaximum size of an acceptable packet.
- END_OF_FILE
- if test 2493 -ne `wc -c <'stream/README'`; then
- echo shar: \"'stream/README'\" unpacked with wrong size!
- fi
- # end of 'stream/README'
- fi
- if test -f 'stream/inet.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stream/inet.h'\"
- else
- echo shar: Extracting \"'stream/inet.h'\" \(417 characters\)
- sed "s/^X//" >'stream/inet.h' <<'END_OF_FILE'
- X#define TRUE 1
- X#define FALSE 0
- X
- X#define PORT_TYPE_NAME 1
- X#define PORT_TYPE_NUMBER 2
- X
- X#define PORT_NAME(name) PORT_TYPE_NAME,name,(u_short)0
- X#define PORT_NUMBER(number) PORT_TYPE_NUMBER,0,(u_short)number
- X
- X/* sockettypes are SOCKET_STREAM and SOCKET_DGRAM */
- X
- X#define DATAGRAM_FLAGS 0 /* for recv and sendto */
- X
- X#define SERVER 1
- X#define CLIENT 2
- X#define server (role == SERVER)
- X#define client (role == CLIENT)
- END_OF_FILE
- if test 417 -ne `wc -c <'stream/inet.h'`; then
- echo shar: \"'stream/inet.h'\" unpacked with wrong size!
- fi
- # end of 'stream/inet.h'
- fi
- if test -f 'stream/reader.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stream/reader.c'\"
- else
- echo shar: Extracting \"'stream/reader.c'\" \(729 characters\)
- sed "s/^X//" >'stream/reader.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include "inet.h"
- X
- Xchar buf[2000];
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X int writer;
- X int cc;
- X int fd;
- X int fds = 0;
- X
- X /* if an arg is provided, use that as the hostname to look for the */
- X /* service */
- X fd = initport(PORT_NUMBER(2000),SERVER,SOCK_STREAM,(char *)0);
- X if (fd < 0) {
- X fprintf(stderr,"initport() = %d\n",fd);
- X exit(-1);
- X }
- X
- X while (TRUE) {
- X writer = select_server_stream(fd,&fds);
- X cc = sized_read(writer,buf,2000);
- X if (cc <= 0) {
- X printf("%d: EOF\n",writer);
- X close(writer);
- X continue;
- X }
- X printf("%d: %s\n",writer,buf);
- X if (cc == 1) cc = sized_write(writer,"1 char",6);
- X }
- X}
- END_OF_FILE
- if test 729 -ne `wc -c <'stream/reader.c'`; then
- echo shar: \"'stream/reader.c'\" unpacked with wrong size!
- fi
- # end of 'stream/reader.c'
- fi
- if test -f 'stream/stream.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stream/stream.3'\"
- else
- echo shar: Extracting \"'stream/stream.3'\" \(2306 characters\)
- sed "s/^X//" >'stream/stream.3' <<'END_OF_FILE'
- X.TH SIZED_IO 3NBS "11 January 1988"
- X.SH NAME
- Xinitport, sized_read, sized_write - send datagrams using TCP
- X.SH SYNOPSIS
- X.B #include <sys/socket.h>
- X.br
- X.B #include <netinet/in.h>
- X.br
- X.B #include <inet.h>
- X.PP
- X.B int s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM);
- X.PP
- X.B int client = select_server_stream(s,&fds);
- X.br
- X.B int s;
- X.br
- X.B int fds;
- X.PP
- X.B int cc = sized_read(fd,buffer,maxsize)
- X.br
- X.B int cc = sized_write(fd,buffer,size)
- X.br
- X.B int fd;
- X.br
- X.B char *buffer;
- X.br
- X.B int maxsize;
- X.SH DESCRIPTION
- XThis package implements packet or stream IO between a server
- Xprocess and a number of client processes, using the TCP/IP (stream)
- Xfacilities. It is particularly useful to send packets larger than
- Xthat allowed by UDP. UDP packets are also not reliable - these are.
- X.PP
- XA client uses the call:
- X.PP
- X.B s = initport(PORT_NUMBER(XXX),CLIENT,SOCK_STREAM);
- X.PP
- Xs is the server's data socket and is used as a file descriptor in further
- Xcommunication. The port may be specified by name (PORT_NAME("foo")), if it
- Xis registered.
- X.PP
- XSimilarly, the server uses the following call:
- X.PP
- X.B s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM);
- X.PP
- Xs is the server's connection socket. To receive data or connections, the
- Xserver calls select_server_stream().
- X.PP
- X.B client = select_server_stream(s,&fds);
- X.PP
- XThis returns a file descriptor corresponding to a client, when a client has
- Xsent a message to the server. It handles initial connections as well as
- Xclient deaths. s is the server's connection socket that was returned by
- Xinitport(). fds is an int used by select...() for storing a bit string
- Xcorresponding to client sockets. Initialize it to 0, and don't mess with it
- Xafter that.
- X.PP
- XTo use the file descriptors in a stream-oriented manner, use read() and
- Xwrite(). To use the file descriptors in a packet-oriented manner, use
- Xsized_read() and sized_write(). The sized...() calls read and write one
- Xpacket at a time, while packet boundaries are ignored in read() and write().
- X.PP
- X.B cc = sized_read(fd,buffer,maxsize)
- X.PP
- X.B cc = sized_write(fd,buffer,size)
- X.PP
- XThe arguments for sized_read() and sized_write() are very similar to read()
- Xand write(). The only difference is that in sized_read(), maxsize is the
- Xmaximum size of an acceptable packet.
- X.SH AUTHOR
- XDon Libes - National Bureau of Standards
- END_OF_FILE
- if test 2306 -ne `wc -c <'stream/stream.3'`; then
- echo shar: \"'stream/stream.3'\" unpacked with wrong size!
- fi
- # end of 'stream/stream.3'
- fi
- if test -f 'stream/writer.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stream/writer.c'\"
- else
- echo shar: Extracting \"'stream/writer.c'\" \(763 characters\)
- sed "s/^X//" >'stream/writer.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X/* #include <netdb.h> */
- X#include "inet.h"
- X
- Xchar msg[2000];
- X
- Xstruct timeval timeout = {0L, 0L};
- Xint maxfds;
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X int cc;
- X int i;
- X int fd;
- X int readfds;
- X
- X maxfds = getdtablesize();
- X fd = initport(PORT_NUMBER(2000),CLIENT,SOCK_STREAM,argc>1?argv[1]:"");
- X
- X if (fd < 0) {
- X fprintf(stderr,"initport() = %d\n",fd);
- X exit(-1);
- X }
- X for (i=0;;i++) {
- X printf("%d: ",i);
- X gets(msg);
- X cc = sized_write(fd,msg,strlen(msg)+1);
- X readfds = 1<<fd;
- X if (0 < select(maxfds,&readfds,0,0,&timeout)
- X && readfds == 1<<fd) {
- X cc = sized_read(fd,msg,2000);
- X msg[cc] = '\0';
- X printf("msg from server: %s\n",msg);
- X }
- X }
- X}
- END_OF_FILE
- if test 763 -ne `wc -c <'stream/writer.c'`; then
- echo shar: \"'stream/writer.c'\" unpacked with wrong size!
- fi
- # end of 'stream/writer.c'
- fi
- echo shar: End of archive 1 \(of 4\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-